#ifndef SDK_OHOS_OHOS_RTP_TRANSCEIVER_H_
#define SDK_OHOS_OHOS_RTP_TRANSCEIVER_H_

#include "api/rtp_transceiver_interface.h"
#include "api/rtp_sender_interface.h"
#include "api/rtp_receiver_interface.h"
#include "api/ohos_rtp_sender_interface.h"
#include "api/ohos_rtp_receiver_interface.h"
#include "api/ohos_rtp_transceiver_interface.h"
#include "api/ohos_peer_connection_factory_interface.h"

namespace ohoswebrtc {

class OHOSRtpTransceiver : public OHOSRtpTransceiverInterface {
  public:

    OHOSRtpTransceiver(rtc::scoped_refptr<webrtc::RtpTransceiverInterface> rtp_transceiver, rtc::scoped_refptr<OHOSPeerConnectionFactoryInterface> peer_connection_factory);
    virtual ~OHOSRtpTransceiver();

    /** Media type of the transceiver. The sender and receiver will also have this
     *  type.
     */
    cricket::MediaType media_type() const override {
      return rtp_transceiver_->media_type();
    }

    /** The mid attribute is the mid negotiated and present in the local and
     *  remote descriptions. Before negotiation is complete, the mid value may be
     *  nil. After rollbacks, the value may change from a non-nil value to nil.
     */
    const absl::optional<std::string> mid() const override;

    /** The sender attribute exposes the RTCRtpSender corresponding to the RTP
     *  media that may be sent with the transceiver's mid. The sender is always
     *  present, regardless of the direction of media.
     */
    rtc::scoped_refptr<OHOSRtpSenderInterface> sender() const override;

    /** The receiver attribute exposes the RTCRtpReceiver corresponding to the RTP
     *  media that may be received with the transceiver's mid. The receiver is
     *  always present, regardless of the direction of media.
     */
    rtc::scoped_refptr<OHOSRtpReceiverInterface> receiver() const override;

    /** Direction of the RtpTransceiver */
    webrtc::RtpTransceiverDirection direction() const override {
      return rtp_transceiver_->direction();
    }

     /** Set Direction of the RtpTransceiver */
    void SetDirection(webrtc::RtpTransceiverDirection new_direction) override {
      rtp_transceiver_->SetDirectionWithError(new_direction);
    }

    /** The current_direction attribute indicates the current direction negotiated for this transceiver.  */
    absl::optional<webrtc::RtpTransceiverDirection> current_direction() const override;

    /** An internal slot designating for which direction the relevant PeerConnection events have been fired*/
    absl::optional<webrtc::RtpTransceiverDirection> fired_direction() const override;

    /** The stopped attribute indicates that the sender of this transceiver will no
     * longer send, and that the receiver will no longer receive. It is true if
     * either stop has been called or if setting the local or remote description
     * has caused the RtpTransceiver to be stopped.
     */
    bool Stopped() const override {
      return rtp_transceiver_->stopped();
    }

    /** The stopping attribute indicates that the user has indicated that the
     * sender of this transceiver will stop sending, and that the receiver will
     * no longer receive. It is always true if stopped() is true.
     * If stopping() is true and stopped() is false, it means that the
     * transceiver's stop() method has been called, but the negotiation with
     * the other end for shutting down the transceiver is not yet done. 
    */
    bool Stopping() const override {
      return rtp_transceiver_->stopping();
    }
    
    /** Initiates a stop of the transceiver.
     * The stop is complete when stopped() returns true.
     * A stopped transceiver can be reused for a different track. 
     */
    webrtc::RTCError StopStandard() override {
      return rtp_transceiver_->StopStandard();
    }

    /** Stops a transceiver immediately, without waiting for signalling.
     * This is an internal function, and is exposed for historical reasons.
     */
    void StopInternal() override {
      return rtp_transceiver_->StopInternal();
    }
  
    /** The SetCodecPreferences method overrides the default codec preferences used by WebRTC for this transceiver. */
    void SetCodecPreferences(rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override {
      rtp_transceiver_->SetCodecPreferences(codecs);
    }
  
    /**  Returns the set of header extensions that was set
     *with SetHeaderExtensionsToNegotiate, or a default set if it has not been called.
    */
    std::vector<webrtc::RtpHeaderExtensionCapability> GetHeaderExtensionsToNegotiate() const override {
      return rtp_transceiver_->GetHeaderExtensionsToNegotiate();
    }

    /** Returns either the empty set if negotation has not yet
     * happened, or a vector of the negotiated header extensions.
     */
    std::vector<webrtc::RtpHeaderExtensionCapability> GetNegotiatedHeaderExtensions() const override {
      return rtp_transceiver_->GetNegotiatedHeaderExtensions();
    }

    /** The SetHeaderExtensionsToNegotiate method modifies the next SDP negotiation
     * so that it negotiates use of header extensions which are not kStopped.
     */
    webrtc::RTCError SetHeaderExtensionsToNegotiate(
      rtc::ArrayView<const webrtc::RtpHeaderExtensionCapability> header_extensions) override {
      return rtp_transceiver_->SetHeaderExtensionsToNegotiate(header_extensions);
    }
    
    /** native rtp_transceiver*/
    rtc::scoped_refptr<webrtc::RtpTransceiverInterface> rtp_transceiver() override {
      return rtp_transceiver_;
    }

  private:
    rtc::scoped_refptr<webrtc::RtpTransceiverInterface> rtp_transceiver_;
    rtc::scoped_refptr<OHOSPeerConnectionFactoryInterface> peer_connection_factory_;
};

}  

#endif  